package com.rmb.util;

import java.sql.*;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author ZhaoMuYang
 * @date 2021年1月8日
 */
public class JdbcConnector {

    private static final String MYSQL_DRIVER = "com.mysql.cj.jdbc.Driver";
    private static final String MYSQL_PRE = "jdbc:mysql://";
    private static final String MYSQL = "MySql";

    private static final String ORACLE_DRIVER = "oracle.jdbc.driver.OracleDriver";
    private static final String ORACLE_PRE = "jdbc:oracle:thin:@";
    private static final String ORACLE = "oracle";

    private static final String SQLSERVER_DRIVER = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
    private static final String SQLSERVER_PRE = "jdbc:sqlserver://";
    private static final String SQLSERVER = "sqlServer";

    private static final String ORACLE_TEST_SQL = "select * from $version";
    private static final String MYSQL_SQLSERVER_TEST_SQL = "select @@version as version";
    private static final String IS_WORKING = "0";
    private static final Integer SYNCHRONIZED_LOCK = 4396;

    private static final String EXTRACONFIGOARAM="?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&serverTimezone=Asia/Shanghai";


    public static final Map<Long, Connection> MYJDBC_CONNECTION_MAP = new ConcurrentHashMap<>(64);

    private static Connection createConnection (com.rmb.entity.SourceEntity info) {

        StringBuilder stringBuilder = new StringBuilder();
        if (MYSQL.equalsIgnoreCase(info.getSourceType())) {
            stringBuilder.append(MYSQL_PRE).append(info.getHost()).append(":").append(info.getPort()+"/").append(info.getDatabaseName());
                stringBuilder.append(EXTRACONFIGOARAM);
        } else if (info.getSourceType() == ORACLE) {
            stringBuilder.append(ORACLE_PRE).append(info.getHost()).append(":").append(info.getPort());
        } else if (info.getSourceType() == SQLSERVER) {
            stringBuilder.append(SQLSERVER_PRE).append(info.getHost()).append(":").append(info.getPort());
        } else {
            return null;
        }
        String url = stringBuilder.toString();
        Connection conn = null;
        try {
            conn = DriverManager.getConnection(url, info.getUsername(),info.getPassword());
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return conn;
    }

    /**
     * @Description 初始化连接池
     * @Date 2021-01-07 10:21
     * @param info 所有数据源信息
     */
    public static void initJdbcPoolMap(List<com.rmb.entity.SourceEntity> info){
        info.forEach(JdbcConnector::put);
    }

    /**
     * @Description 向连接池 添加新连接/更新
     * @Date 2021-01-07 10:22
     * @param dataSource 数据源信息
     */
    public static Boolean put(com.rmb.entity.SourceEntity dataSource){
        Connection connection = createConnection(dataSource);
        if(connection!=null){
            Boolean connected = isConnected(connection, dataSource);
            if(connected){
                MYJDBC_CONNECTION_MAP.put(dataSource.getId(), connection);
            }
            return true;
        }
        return false;
    }

    private static Boolean isConnected(Connection connection,com.rmb.entity.SourceEntity dataSource){
        boolean flag=false;
        try {
            Statement statement = connection.createStatement();
            ResultSet resultSet = statement.executeQuery(MYSQL_SQLSERVER_TEST_SQL);
            if (dataSource.getSourceType()==ORACLE){
                resultSet = statement.executeQuery(ORACLE_TEST_SQL);
            }else if(dataSource.getSourceType()==SQLSERVER){
                resultSet = statement.executeQuery(MYSQL_SQLSERVER_TEST_SQL);
            }
            while (resultSet.next()){
                String version = resultSet.getString("version");
                if(version!=null){
                    flag=true;
                    System.out.println(version);
                }
            }
            if(dataSource.getId()==null){
                connection.close();
            }
            statement.close();
            resultSet.close();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return flag;
    }

    public static Boolean isConnected(com.rmb.entity.SourceEntity dataSource){
        Connection connection;
        if(dataSource!=null && dataSource.getId()!=null){
            connection = MYJDBC_CONNECTION_MAP.get(dataSource.getId());
        }else{
            connection = createConnection(dataSource);
        }

        return isConnected(connection, dataSource);
    }

    /**
     * @Description 关闭所有连接
     * @Author WangZhuoRan
     * @Date 2021-01-07 09:19
     */
    public static void closeAll(){
        MYJDBC_CONNECTION_MAP.forEach((id, connection) -> {
            try {
                connection.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        });
    }

    /**
     * @Description 判断是否在工作
     * @Author WangZhuoRan
     * @Date 2021-01-07 10:21
     * @param connection 判断的数据源连接对象
     * @return java.lang.Boolean
     */
    public static Boolean isNotWorked (Connection connection){
        try {
            String query = connection.getClientInfo("isworking");
            if (query==null || IS_WORKING.equals(query)){
                return true;
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return false;
    }

}
